home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 January / macformat-033.iso / mac / Shareware City / Developers / ABox.v1.8 / CPlus Files / ABUText.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  13.5 KB  |  574 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10.     This file is based upon work produced by Greg Anderson (Apple DTS).
  11.  
  12. Product
  13.     About Box
  14.  
  15. FILE
  16.     ABUText.c
  17.  
  18. NAME
  19.     ABUText.c, part of the ABox project source code,
  20.     responsible for mix-in handling the AboutBox text
  21.     utilities stuff, such as scroll bar synchronization, line
  22.     heights, etc.
  23.  
  24. DESCRIPTION
  25.     This file contains defines for the about box modules.
  26.     
  27. DEVELOPED BY
  28.     George (ty) Tempel                netromancr@aol.com
  29.     All code in this file, and its associated header file was
  30.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  31.     "FilterTop" application development, except where noted.
  32.  
  33. CARETAKER - George (ty) Tempel <netromancr@aol.com>
  34.      Please consult this person for any changes or suggestions to this file.
  35.  
  36. MODIFICATION HISTORY
  37.  
  38.     dd mmm yy    -    xxx    -    patchxx: description of patch
  39.     10 June 94    -    ty    -    Initial Version Created
  40.     20-july-94    -    ty    -    initial version released
  41.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  42.                             release and the associated Universal Headers from Apple:
  43.                             most methods that returned references now have "Ref" at
  44.                             the end of their methods names to prevent possible collisions
  45.                             with datatypes and classes of the same name (older versions
  46.                             of the compiler didn't have a problem with this).
  47.  
  48. */
  49.  
  50. /*===========================================================================*/
  51.  
  52. /*======= Segmentation directives ========*/
  53.  
  54. #ifdef USE_MANUAL_SEGMENTATION
  55. #pragma segment ty
  56. #endif
  57.  
  58. /*============ Header files ==============*/
  59.     
  60. #include     "ABUText.h"
  61.  
  62. /*=============== Globals ================*/
  63.  
  64.  
  65. /*================ CODE ==================*/
  66.  
  67.  
  68. /*=============================== ABUText::ABUText ================================*/
  69. ABUText::ABUText(void)
  70. {
  71. }    // end ABUText
  72.  
  73.  
  74. /*=============================== ABUText::~ABUText ================================*/
  75. ABUText::~ABUText(void)
  76. {
  77. }    // end ~ABUText
  78.  
  79.  
  80.  
  81.  
  82. /*=============================== ABUText::TEGetSelect ==================================*/
  83. //
  84. // Get the current selection
  85.  
  86. //    is called by:
  87. //        external code; this is a public method
  88. //
  89. void ABUText::TEGetSelect(short* selStart, short* selEnd, TEHandle te)
  90. {
  91.     //    metro: ty...addition to trap bad parameters
  92.     if(!(selStart && selEnd && te))
  93.         return;
  94.  
  95.     *selStart = (*te)->selStart;
  96.     *selEnd    = (*te)->selEnd;
  97. }
  98.  
  99.  
  100. /*=============================== ABUText::TEGetChars ==================================*/
  101. //
  102. // Get some characters from the TextEdit record
  103.  
  104. //    is called by:
  105. //        external code; this is a public method
  106. //
  107. void ABUText::TEGetChars(char *buf, short from, short to, TEHandle te)
  108. {
  109.     CharsHandle        theText = NULL;
  110.     short            theState;
  111.     unsigned char    *ptr;
  112.     
  113.     //    metro: ty...addition to trap bad parameters
  114.     if (!te  || !buf)
  115.         return;
  116.         
  117.     theText = ::TEGetText(te);
  118.  
  119.     if (!theText)
  120.         return;
  121.         
  122.     theState = ::HGetState((Handle) theText);
  123.     ::HLock((Handle) theText);
  124.     ptr = (unsigned char*) (*theText);
  125.     ptr += from; 
  126.     ::BlockMove(ptr, buf, to - from);
  127.     buf[to - from] = 0;
  128.     ::HSetState((Handle) theText, theState);
  129. }
  130.  
  131.  
  132. /*=============================== ABUText::GetTEView ==================================*/
  133. //
  134. // Return the current view rectangle of the given textedit record
  135.  
  136. //    is called by:
  137. //        ViewHeight
  138. //
  139. void ABUText::GetTEView(TEHandle te, Rect *viewRect)
  140. {
  141.     //    metro: ty...addition to trap bad parameters
  142.     if(!(te && viewRect))
  143.         return;
  144.     *viewRect = (*te)->viewRect;
  145. }
  146.  
  147. /*=============================== ABUText::TELines ==================================*/
  148. //
  149. // Return the number of lines in the current textedit buffer
  150. //
  151. //    returns 0 if there are bad parameters.
  152. //
  153. //    is called by:
  154. //        TEHeight
  155. //
  156. short ABUText::TELines(TEHandle te)
  157. {
  158.     //    metro: ty...addition to trap bad parameters
  159.     if (!te)
  160.         return 0;                // 1.0a2 SJ added the 0
  161.     else
  162.         return((*te)->nLines);
  163. }
  164.  
  165. /*=============================== ABUText::TEHeight ==================================*/
  166. //
  167. // Return the pixel height of the current textedit buffer
  168.  
  169. //    is called by:
  170. //        VScrollLocation
  171. //        PinnedTEVScroll
  172. //        TEVThumbScroll
  173. //
  174. short ABUText::TEHeight(TEHandle te)
  175. {
  176.     //    metro: ty...addition to trap bad parameters
  177.     if(!te)        //    metro: ty...addition to trap bad parameters
  178.         return 0;
  179.     else
  180.         return ::TEGetHeight(ABUText::TELines(te), 0, te);
  181. }
  182.  
  183. /*=============================== ABUText::TELineHeight ==================================*/
  184. //
  185. // Return the number of pixels in one line
  186.  
  187. //    is called by:
  188. //        PinnedTEVScroll
  189. //        TEVThumbScroll
  190. //        ScrollTELine
  191. //        ScrollTEPage
  192. //
  193. short ABUText::TELineHeight(TEHandle te)
  194. {
  195.     //    metro: ty...addition to trap bad parameters
  196.     if(!te)                
  197.         return 0;
  198.  
  199.     if((*te)->lineHeight == -1)
  200.         return kTEUdefaultLineHeight;
  201.     else
  202.         return (*te)->lineHeight;
  203. }
  204.  
  205. /*=============================== ABUText::GetTEVScroll ==================================*/
  206. //
  207. //    Return the number of pixels to the current scroll location
  208.  
  209. //    is called by:
  210. //        PinnedTEVScroll
  211. //        TEVThumbScroll
  212. //        VScrollLocation
  213. //
  214. short ABUText::GetTEVScroll(TEHandle te)
  215. {
  216.     //    metro: ty...addition to trap bad parameters
  217.     if(!te)
  218.         return 0;                                        // 1.0a2 SJ added the 0
  219.     else
  220.         return ((*te)->viewRect.top - (*te)->destRect.top);
  221. }
  222.  
  223. /*=============================== ABUText::ViewHeight ==================================*/
  224. //
  225. // Return the pixel height of the view rectangle
  226.  
  227. //    is called by:
  228. //        PinnedTEVScroll
  229. //        VScrollLocation
  230. //        TEVThumbScroll
  231. //        ScrollTEPage
  232. //
  233. short ABUText::ViewHeight(TEHandle te)
  234. {
  235.     Rect    viewRect;
  236.  
  237.     //    metro: ty...addition to trap bad parameters
  238.     if(!te)
  239.         return 0;
  240.         
  241.     ABUText::GetTEView(te, &viewRect);
  242.     
  243.     return (viewRect.bottom - viewRect.top);
  244. }
  245.  
  246. /*=============================== ABUText::VScrollLocation ==================================*/
  247. //
  248. //    Return a number from 1 - 1000 (GetCtlMin() - GetCtlMax()) indicating the 
  249. //    current scroll location of the textedit record
  250.  
  251. //    is called by:
  252. //        FixScrollBar
  253. //
  254. short ABUText::VScrollLocation(ControlHandle scrollbar)
  255. {
  256.     long tmp;
  257.     
  258.     TEHandle    te = (TEHandle) ::GetCRefCon(scrollbar);
  259.     
  260.     //    metro: ty...addition to trap bad parameters
  261.     if (!te)
  262.         return 1;
  263.     tmp = ABUText::GetTEVScroll(te) * (long) ::GetCtlMax(scrollbar);
  264.     tmp /= (ABUText::TEHeight(te) - ABUText::ViewHeight(te));
  265.     
  266.     return tmp;
  267. }
  268.  
  269. /*=============================== ABUText::PinnedTEVScroll ==================================*/
  270. //
  271. //    Call TEScroll, but don't scroll past top or below bottom    
  272. //    This code also adjusts the scrollbar.
  273.  
  274. //    is called by:
  275. //        TEVThumbScroll
  276. //        ScrollTELine
  277. //        ScrollTEPage
  278. //
  279. void ABUText::PinnedTEVScroll(TEHandle te, ControlHandle scrollbar, short dv)
  280. {
  281.     short    max;
  282.     short    lineh = ABUText::TELineHeight(te);
  283.     
  284.     //    metro: ty...addition to trap bad parameters
  285.     if(!(te && scrollbar))
  286.         return;
  287.         
  288.     if(lineh == -1)
  289.         lineh = kTEUdefaultLineHeight;
  290.     
  291.     if(dv > 0) 
  292.     {
  293.         max = ABUText::GetTEVScroll(te);
  294.         if(dv > max)
  295.             dv = max;
  296.     } 
  297.     else 
  298.     {
  299.         max = ABUText::TEHeight(te) - ABUText::ViewHeight(te) - ABUText::GetTEVScroll(te) - 1;
  300.         max = max - (max % lineh) + lineh;
  301.         if(max < 0)
  302.             max = 0;
  303.         if((-dv) > max)
  304.             dv = -max;
  305.     }
  306.     
  307.     ::TEScroll(0,dv,te);
  308.     ABUText::FixScrollBar(scrollbar);
  309. }
  310.  
  311. /*=============================== ABUText::TEVThumbScroll ==================================*/
  312. //
  313. // Scroll directly to a new location.
  314. //
  315. //    is called by:
  316. //        TrackUpDownPage
  317. //        ScrollBarClick
  318. //
  319. void ABUText::TEVThumbScroll(TEHandle te, ControlHandle scrollbar)
  320. {
  321.     long        newScroll;
  322.     short        deltaScroll;
  323.     
  324.     //    metro: ty...addition to trap bad parameters
  325.     if(!(te && scrollbar))
  326.         return;
  327.         
  328.     /*
  329.     // 'GetCtlValue' ranges from 0 to 1000.  Convert this into a textedit range
  330.     // of zero to (texteditHeight - viewHeight)
  331.     */
  332.     
  333.     newScroll  = ::GetCtlValue(scrollbar);
  334.     newScroll *= (ABUText::TEHeight(te) -ABUText:: ViewHeight(te));
  335.     newScroll /= (long)::GetCtlMax(scrollbar);
  336.     
  337.     /*
  338.     // We don't want to scroll to just any pixel, though...
  339.     */
  340.     
  341.     newScroll /= ABUText::TELineHeight(te);
  342.     newScroll *= ABUText::TELineHeight(te);
  343.     
  344.     /*
  345.     // Now find out where we are, and how far we have to move to get to
  346.     // where we want to go.
  347.     */
  348.     
  349.     deltaScroll = ABUText::GetTEVScroll(te) - newScroll;
  350.     ABUText::PinnedTEVScroll(te, scrollbar, deltaScroll);
  351. }
  352.  
  353. /*=============================== ABUText::ScrollTELine ==================================*/
  354. //
  355. // Scroll up or down one line
  356. //
  357. //    is called by:
  358. //        TrackUpDownArrows
  359. //
  360. void ABUText::ScrollTELine(TEHandle te, ControlHandle scrollbar, short dir)
  361. {
  362.     //    metro: ty...addition to trap bad parameters
  363.     if (!(te && scrollbar))
  364.         return;
  365.         
  366.     ABUText::PinnedTEVScroll(te, scrollbar, dir * ABUText::TELineHeight(te));
  367. }
  368.  
  369. /*=============================== ABUText::ScrollTEPage ==================================*/
  370. //
  371. //    Scroll up or down one page
  372. //
  373. //    is called by:
  374. //        TrackUpDownPage
  375. //
  376. void ABUText::ScrollTEPage(TEHandle te, ControlHandle scrollbar, short dir)
  377. {
  378.     short        linePix;
  379.     short        pagePix;
  380.     short        pageLines;
  381.     
  382.     //    metro: ty...addition to trap bad parameters
  383.     if (!(te && scrollbar))
  384.         return;
  385.         
  386.     pagePix = ABUText::ViewHeight(te);
  387.     linePix = ABUText::TELineHeight(te);
  388.     pageLines = pagePix / linePix;
  389.     pagePix = (pageLines - 1) * linePix;
  390.     
  391.     ABUText::PinnedTEVScroll(te, scrollbar, dir * pagePix);
  392. }
  393.  
  394. /*=============================== ABUText::TrackUpDownArrows ==================================*/
  395. //
  396. // This routine is called repeatedly while the scroll bar is tracked.
  397. //
  398. // 1.0a2 SJ added the void return type below:
  399. //
  400. //    is called by:
  401. //        ScrollBarClick
  402. //
  403. pascal void ABUText::TrackUpDownArrows(ControlHandle theControl, short partCode)
  404. {
  405.     TEHandle    te;
  406.     
  407.     //    begin here...
  408.     //    metro: ty...addition to trap bad parameters
  409.     if (!theControl)
  410.         return;
  411.     else
  412.         te = (TEHandle) ::GetCRefCon(theControl);
  413.  
  414.     if((te && theControl))
  415.         switch(partCode)    
  416.         {
  417.             case     inUpButton:
  418.             
  419.                     ABUText::ScrollTELine(te, theControl, kTEUscrollForwardOneUnit);
  420.                     break;
  421.                     
  422.             case inDownButton:
  423.             
  424.                     ABUText::ScrollTELine(te, theControl, kTEUscrollBackwardOneUnit);
  425.                     break;
  426.                     
  427.         }
  428. }
  429.  
  430. /*=============================== ABUText::TrackUpDownPage ==================================*/
  431. //
  432. // This routine is called repeatedly while the scroll bar is tracked.
  433. //
  434. // 1.0a2+ ty created from a copy of TrackUpDownArrows()
  435. //
  436. //    is called by:
  437. //        ScrollBarClick
  438. //
  439. pascal void ABUText::TrackUpDownPage(ControlHandle theControl, short partCode)
  440. {
  441.     TEHandle    te;
  442.     
  443.     //    begin here...
  444.     //    metro: ty...addition to trap bad parameters
  445.     if (!theControl)
  446.         return;
  447.     else
  448.         te = (TEHandle) ::GetCRefCon(theControl);
  449.  
  450.     if((te && theControl))
  451.         switch(partCode) 
  452.         {
  453.             case     inPageUp:
  454.             
  455.                     ABUText::ScrollTEPage(te, theControl, kTEUscrollForwardOneUnit);
  456.                     break;
  457.  
  458.             case     inPageDown:
  459.             
  460.                     ABUText::ScrollTEPage(te, theControl, kTEUscrollBackwardOneUnit);
  461.                     break;
  462.                 
  463.             case     inThumb:
  464.             
  465.                     ABUText::TEVThumbScroll(te, theControl);
  466.                     break;
  467.                 
  468.         } 
  469. }
  470.  
  471. /*=============================== ABUText::ScrollBarClick ==================================*/
  472. //
  473. //    Interact with a VERTICAL scroll bar
  474. //    
  475. //    Pass a handle to the scrollbar's control record and the point (in LOCAL
  476. //    coordinates) where the mouse hit the scrollbar.
  477. //    
  478. //    WARNING:    The refCon of the scrollbar MUST point to the textedit record
  479. //                That it is associated with.
  480. //
  481. //    is called by:
  482. //        external code; this is called by the using-application
  483. //
  484.  
  485. void ABUText::ScrollBarClick(ControlHandle scrollbar, Point where)
  486. {
  487.     TEHandle            te = NULL;
  488.     ControlActionUPP    actionUPP;
  489.  
  490.     /*
  491.     // Ponnuki always sets the refCon of a scrollbar to the
  492.     // TEHandle associated with that scrollbar
  493.     */
  494.     
  495.     if (!scrollbar) 
  496.     {
  497.         return;
  498.     } 
  499.     else if ((*scrollbar)->contrlHilite == 255) 
  500.     {
  501.         //    control is not active, so bail out.
  502.         return;
  503.     }
  504.         
  505.     te = (TEHandle) ::GetCRefCon(scrollbar);
  506.     if (!te)
  507.         return;
  508.         
  509.     /*
  510.     // TrackControl passes different parameters to 'trackAction' based on
  511.     // what type of control it is tracking & what part of the control the
  512.     // mouse is in.  Therefore, we cannot simply use the same trackAction
  513.     // procedure for every 'TrackControl' that might come through this
  514.     // routine.    :<  Fortunately, we only need to call a 'trackAction'
  515.     // proc for the up and down facing buttons.
  516.     */
  517.     
  518.     switch(TestControl(scrollbar,where)) 
  519.     {
  520.         case     inUpButton:
  521.         case     inDownButton:
  522.         
  523.                 //    do the power pc thing!
  524.                 actionUPP = NewControlActionProc(ABUText::TrackUpDownArrows);
  525.                 ::TrackControl(scrollbar,where, actionUPP);
  526.                 DisposeRoutineDescriptor(actionUPP);
  527.                 break;
  528.             
  529.         case     inPageUp:
  530.         case     inPageDown:
  531.         
  532.                 //    do the power pc thing!
  533.                 actionUPP = NewControlActionProc(ABUText::TrackUpDownPage);        //    1.0a4 ty fixed
  534.                 ::TrackControl(scrollbar, where, actionUPP);
  535.                 DisposeRoutineDescriptor(actionUPP);
  536.                 break;
  537.             
  538.         case     inThumb:
  539.         
  540.                 ::TrackControl(scrollbar,where, (ControlActionUPP) 0L);    // 1.0a4 SJ cast
  541.                 ABUText::TEVThumbScroll(te, scrollbar);
  542.                 break;
  543.     }
  544. }
  545.  
  546. /*=============================== ABUText::FixScrollBar ==================================*/
  547. //
  548. //    Fix a VERTICAL scroll bar after a TE field has been scrolled 
  549. //    
  550. //    Pass a handle to the scrollbar's control record
  551. //    
  552. //    WARNING:    The refCon of the scrollbar MUST point to the textedit record
  553. //    That it is associated with.
  554. //
  555. //    is called by:
  556. //        PinnedTEVScroll
  557. //
  558. void ABUText::FixScrollBar(ControlHandle scrollbar)
  559. {
  560.     //TEHandle    te;
  561.  
  562.     /*
  563.     // Ponnuki always sets the refCon of a scrollbar to the
  564.     // TEHandle associated with that scrollbar
  565.     */
  566.     
  567.     if(!scrollbar)
  568.         return;
  569.         
  570.     //te = (TEHandle) GetCRefCon(scrollbar);
  571.     ::SetCtlValue(scrollbar, ABUText::VScrollLocation(scrollbar));
  572.     ::Draw1Control(scrollbar);
  573. }
  574.